﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.IO;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using ParsePtb.Comm;
using ParsePtb.consts;
using ParsePtb.util;
using ParseTask;

namespace ParsePtb
{
    public partial class UploadFrm : Form
    {
        private FtpClient _ftp = null;

        //初始化时上传的数量
        private int initParseCount = 0;

        //初始化时上传结束成功的数量
        private int parseSuccessCount = 0;

        // 初始化时上传结束的失败数
        private int parseFailCount = 0;

        private static string title = "文件上传";

        private static bool IS_UPLOADING = false;

        //db文件的记录 防止重复
        private Dictionary<string, FileInfo> listDict = new Dictionary<string, FileInfo>();

        string sqliteLocation = ConfigurationManager.AppSettings.Get("dbRootFolder");

        string sqliteDbName = ConfigurationManager.AppSettings.Get("dbName");

        private string ftpIp = ConfigurationManager.AppSettings.Get("ftpIp");

        //ftp账号
        private string ftpAdmin = ConfigurationManager.AppSettings.Get("ftpAdmin");

        //密码
        private string ftpPwd = ConfigurationManager.AppSettings.Get("ftpPwd");

        //所有的check文件 字典
        private Dictionary<string, FileInfo> confirmDict = new Dictionary<string, FileInfo>();

        private const int BUFFSIZE = 1024 * 2;

        public const int WM_DEVICECHANGE = 0x219;
        public const int DBT_DEVICEARRIVAL = 0x8000;    //如果m.Msg的值为0x8000那么表示有U盘插入
        public const int DBT_CONFIGCHANGECANCELED = 0x0019;
        public const int DBT_CONFIGCHANGED = 0x0018;
        public const int DBT_CUSTOMEVENT = 0x8006;
        public const int DBT_DEVICEQUERYREMOVE = 0x8001;
        public const int DBT_DEVICEQUERYREMOVEFAILED = 0x8002;
        public const int DBT_DEVICEREMOVECOMPLETE = 0X8004;
        public const int DBT_DEVICEREMOVEPENDING = 0x8003;
        public const int DBT_DEVICETYPESPECIFIC = 0x8005;
        public const int DBT_DEVNODES_CHANGED = 0x0007;
        public const int DBT_QUERYCHANGECONFIG = 0x0017;
        public const int DBT_USERDEFINED = 0xFFFF;
        public Message mm;

        private ListViewItem viewItem = null;

        private DateTime _begin;

        private bool stopFlag = false;

        /// <summary>
        /// 监视Windows消息
        /// </summary>
        /// <param name="m"></param>
        protected override void WndProc(ref Message m)
        {
            try
            {
                if (m.Msg == WM_DEVICECHANGE)
                {
                    switch (m.WParam.ToInt32())
                    {
                        case WM_DEVICECHANGE:
                            break;
                        case DBT_DEVICEARRIVAL:         //U盘插入
                            GetDBList();
                            //Console.WriteLine("");
                            //listBox1.Items.Add("U盘已插入,盘符为:" + strDrivers[strDrivers.Count() - 1]);
                            break;
                        case DBT_CONFIGCHANGECANCELED:
                            break;
                        case DBT_CONFIGCHANGED:
                            break;
                        case DBT_CUSTOMEVENT:
                            break;
                        case DBT_DEVICEQUERYREMOVE:
                            Console.WriteLine("DBT_DEVICEQUERYREMOVE");
                            break;
                        case DBT_DEVICEQUERYREMOVEFAILED:
                            Console.WriteLine("DBT_DEVICEQUERYREMOVEFAILED");
                            break;
                        case DBT_DEVICEREMOVECOMPLETE:   //U盘卸载 ==>移除时间
                            Console.WriteLine("DBT_DEVICEREMOVECOMPLETE");
                            RemoveFileList();
                            break;
                        case DBT_DEVICEREMOVEPENDING:
                            Console.WriteLine("DBT_DEVICEREMOVEPENDING");
                            break;
                        case DBT_DEVNODES_CHANGED:
                            Console.WriteLine("DBT_DEVNODES_CHANGED");
                            break;
                        case DBT_QUERYCHANGECONFIG:
                            break;
                        case DBT_USERDEFINED:
                            break;
                        default:
                            break;
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            base.WndProc(ref m); //将系统消息传递自父类的WndProc
        }

        private void RemoveFileList()
        {
            string driver;
            Dictionary<string, List<ListViewItem>> drivers = new Dictionary<string, List<ListViewItem>>();
            string[] strDrivers = Environment.GetLogicalDrives();
            List<ListViewItem> listItem;
            for (int i = 0; i < listViewFiles.Items.Count; i++)
            {
                driver = listViewFiles.Items[i].Text.Split('\\')[0] + "\\";
                //该项不在解析之列--!IS_UPLOADING &&
                if ((viewItem == null || listViewFiles.Items[i].Text != viewItem.Text)
                   )
                {
                    if (!drivers.ContainsKey(driver))
                    {
                        listItem = new List<ListViewItem>();
                        listItem.Add(listViewFiles.Items[i]);
                        drivers.Add(driver, listItem);
                    }
                    else
                    {
                        drivers[driver].Add(listViewFiles.Items[i]);
                    }
                }
            }


            for (int k = 1; k < strDrivers.Length; k++)
            {
                drivers.Remove(strDrivers[k]);//移除存在项  剩下的就是被拔出的U盘
            }

            //该项移除列表
            foreach (var item in drivers)
            {
                foreach (var view in item.Value)
                {
                    listViewFiles.Items.Remove(view);
                    listDict.Remove(view.Text);
                    this.initParseCount--;
                }
            }

            this.lblunanalysedQty.Text = Convert.ToString(this.initParseCount);
        }



        public UploadFrm()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 上传附件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void UpLoadFiles_Click(object sender, System.EventArgs e)
        {

        }



        /// <summary>
        /// 获取db文件的列表
        /// </summary>
        private void GetDBList()
        {
            string[] strDrivers = Environment.GetLogicalDrives();
            //一般磁盘会有2个盘符
            DirectoryInfo directoryInfo;
            FileInfo[] fileInfos;

            //只取最后一个盘符
            for (int i = strDrivers.Length - 1; i < strDrivers.Length; i++)
            {
                directoryInfo = new DirectoryInfo(strDrivers[i]);
                fileInfos = directoryInfo.GetFiles();
                foreach (var item in fileInfos)
                {
                    //enc.zip
                    //加密文件和确认文件
                    if (item.Name.Contains("enc.zip") || item.Name.Contains("_confirm.enc"))
                    {
                        if (listDict.ContainsKey(item.FullName))
                        {
                            continue;
                        }
                        listViewFiles.Items.Add(new ListViewItem() { Text = item.FullName });
                        listDict.Add(item.FullName, item);
                        //记录当前上传的文件数量
                        this.initParseCount++;
                        this.lblunanalysedQty.Text = Convert.ToString(initParseCount);
                    }
                }
            }

        }






        private void UploadFrm_Load(object sender, EventArgs e)
        {
            CheckForIllegalCrossThreadCalls = false;
            LoginFtp();//先登录ftp
        }


        /// <summary>
        /// ftp登录
        /// </summary>
        private void LoginFtp()
        {
            try
            {
                this._ftp = new FtpClient(ftpIp, ftpAdmin, ftpPwd);
                /*  this._ftp.CompleteDownload = null;
                  this._ftp.FailDownload = null;*/
                this._ftp.CompleteUpload = CompleteUpload;
                this._ftp.FailUpload = FailUpload;
            }
            catch (Exception ex)
            {
                this._ftp = null;
                MessageBox.Show(ex.Message);
            }
        }




        /// <summary>
        /// 上传完成
        /// </summary>
        private void CompleteUpload(string localFile)
        {
            this.BeginInvoke(new MethodInvoker(delegate
            {
                if (localFile != null)
                {
                    RemoveListViewItem(localFile);
                    AppendListViewItemToLogs(localFile, "上传完成", ResultEnum.Success);
                    /* RemoveListViewItem(viewItem.Text);
                     AppendListViewItemToLogs(viewItem.Text, "上传完成", ResultEnum.Success);*/
                }
            }));
        }


        /// <summary>
        /// 上传失败
        /// </summary>
        /// <param name="ex"></param>
        private void FailUpload(string localFile, string ex)
        {
            this.BeginInvoke(new MethodInvoker(delegate
            {
                if (localFile != null)
                {
                    /*RemoveListViewItem(viewItem.Text);
                    AppendListViewItemToLogs(viewItem.Text, "上传失败:" + ex, ResultEnum.Fail);*/
                    RemoveListViewItem(localFile);
                    AppendListViewItemToLogs(localFile, "上传失败:" + ex, ResultEnum.Fail);
                }
            }));
        }



        /// <summary>
        /// 上传文件 or 停止上传
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonStart_Click(object sender, EventArgs e)
        {
            if (!"stop".Equals(((Button)sender).Tag))
            {
                if (listViewFiles.Items.Count <= 0)
                {
                    MessageBox.Show("列表没有需要上传的文件!");
                    return;
                }

                this.timer1.Interval = 3000;
                this.timer1.Start();
                this.buttonStart.Text = "停止上传";
                this.buttonStart.Tag = "stop";
                this.buttonStart.ForeColor = Color.Red;
                stopFlag = false;

                this.lblTimerMsg.Text = "正在上传";
                this.lblTimerMsg.Visible = true;
            }
            else//停止
            {
                this.timer1.Stop();
                this.buttonStart.Text = "开始上传";
                this.buttonStart.Tag = "begin";
                this.buttonStart.ForeColor = Color.Black;
                stopFlag = true;
            }


        }

        private void UploadFile()
        {
            try
            {
                if (!IS_UPLOADING)
                {
                    IS_UPLOADING = true;//正在上传
                    ListView.ListViewItemCollection itemList = listViewFiles.Items;
                    string directionPath = "";//文件的文件夹路径

                    foreach (ListViewItem item in itemList)
                    {
                        if (stopFlag)
                        {
                            break;
                        }
                        this._begin = DateTime.Now;
                        directionPath = listDict[item.Text].Directory.FullName;
                        viewItem = item;
                        this._ftp.UploadFile("", item.Text);
                    }

                    IS_UPLOADING = false;//上传完成

                    /*this.buttonStart.Text = "开始上传";
                    this.lblTimerMsg.Visible = false;
                    this.buttonStart.Enabled = true;
                    this.buttonStart.ForeColor = Color.Black;*/
                }
            }
            catch (Exception ex)
            {
                if (viewItem != null)
                {
                    RemoveListViewItem(viewItem.Text);
                    AppendListViewItemToLogs(viewItem.Text, "上传失败:" + ex.Message, ResultEnum.Fail);
                }
            }
        }



        //文件和文件解析状态
        private void AppendListViewItemToLogs(string filePath, string statusMsg, ResultEnum resultEnum)
        {
            StringBuilder sbf = new StringBuilder();
            if (File.Exists(filePath))
            {
                DateTime endTime = DateTime.Now;
                double costTime = endTime.Subtract(this._begin).TotalSeconds;

                string fileName = Path.GetFileName(filePath);
                string curTime = endTime.ToString("yyyy-MM-dd HH:mm:ss");
                ListViewItem listView = new ListViewItem() { Text = curTime };
                listView.SubItems.Add(filePath);//第二列
                listView.SubItems.Add(statusMsg);//第三列
                listView.SubItems.Add(Convert.ToString(costTime));//第四列
                listViewLogs.Items.Add(listView);
                listViewLogs.Refresh();

                sbf.Append($"select *  from SYS_UPLOAD_FILE_LOG where FILE_NAME='{fileName}'");

                DataTable dataTable = SQLiteLibrary.selectDataBySql(sqliteLocation, sqliteDbName, sbf.ToString());

                if (resultEnum == ResultEnum.Success)
                {
                    this.parseSuccessCount++;
                    this.parseSuccess.Text = $"上传成功数:{Convert.ToString(this.parseSuccessCount)}";
                    this.parseSuccess.Update();
                }
                else
                {
                    this.parseFailCount++;
                    this.parseFail.Text = $"上传失败数:{Convert.ToString(this.parseFailCount)}";
                    this.parseFail.Update();
                }

                string sql = dataTable.Rows.Count > 0 ?
                    $"update SYS_UPLOAD_FILE_LOG SET STATUS ='{statusMsg}',FULL_NAME='{filePath}', UPDATE_TIME =datetime('now', 'localtime') where FILE_NAME='{fileName}'"
                    : $"insert into SYS_UPLOAD_FILE_LOG(FULL_NAME,FILE_NAME,STATUS,CREATE_TIME,PARSE) values('{filePath}','{fileName}','{statusMsg}',datetime('now', 'localtime'),'0')";
                SQLiteLibrary.insertData(sqliteLocation, sqliteDbName, sql);


                this.initParseCount = this.initParseCount - 1 >= 0 ? this.initParseCount - 1 : this.initParseCount;
                this.lblunanalysedQty.Text = Convert.ToString(initParseCount);
                this.lblunanalysedQty.Update();
                LogsHelper.addLog($"上传文件:{filePath},状态:{statusMsg}");
            }
        }

        /// <summary>
        /// 暂时不用
        /// </summary>
        /// <param name="filePath"></param>
        private void AppendListViewItem(string filePath)

        {
            if (File.Exists(filePath))
            {
                string fileName = Path.GetFileName(filePath);
                ListViewItem listView = new ListViewItem() { Text = fileName };
                listViewFiles.Items.Add(listView);
                listViewFiles.Refresh();
            }
        }


        /// <summary>
        ///  删除待解析列表的该文件
        /// </summary>
        /// <param name="v"></param>
        private void RemoveListViewItem(string filePath)
        {
            try
            {
                if (File.Exists(filePath))
                {
                    ListView.ListViewItemCollection collection = listViewFiles.Items;
                    for (int i = 0; i < collection.Count; i++)
                    {
                        if (collection[i].Text == filePath)
                        {
                            listViewFiles.Items.RemoveAt(i);
                            listDict.Remove(filePath);
                        }
                    }

                    listViewFiles.Refresh();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
        }

        /// <summary>
        /// 日志清空
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void clearLogBtn_Click(object sender, EventArgs e)
        {
            this.listViewLogs.Items.Clear();
        }

        /// <summary>
        /// 上传任务
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void UpLoadTask(object sender, EventArgs e)
        {
            if (!IS_UPLOADING && !stopFlag)
            {
                //UploadFile();
                Thread thread = new Thread(new ThreadStart(UploadFile));
                thread.Start();
            }
        }


        /// <summary>
        /// 跳往解析
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SkigParse_Click(object sender, EventArgs e)
        {
            Form form = new ParseForm();
            this.AddOwnedForm(form);
            //form.StartPosition = FormStartPosition.CenterParent;
            form.Show();
            this.Hide();
        }


    }
}
